package org.ddd.book.book;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollectionUtil;
import lombok.extern.slf4j.Slf4j;
import org.ddd.book.book.dto.LibraryBaseMessageDTO;
import org.ddd.book.book.dto.LibraryDTO;
import org.ddd.book.book.dto.LibraryInfoDTO;
import org.ddd.book.domain.DomainException;
import org.ddd.book.domain.base.repository.IAddressRepository;
import org.ddd.book.domain.base.vo.AddressVO;
import org.ddd.book.domain.book.entity.LibraryEntity;
import org.ddd.book.domain.book.repository.ILibraryRepository;
import org.ddd.book.domain.book.vo.LibraryBaseInfoVO;
import org.ddd.book.domain.factoty.RepositoryFactory;
import org.ddd.book.domain.security.repository.IUserRepository;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Collections;
import java.util.LinkedList;
import java.util.List;

@Service
@Slf4j
public class LibraryService {

    /**
     * 注册图书馆
     *
     * @param libraryDTO 图书馆
     */
    @Transactional
    public void registerLibrary(LibraryDTO libraryDTO) {
        // 构建参数
        LibraryEntity library = new LibraryEntity();
        library.setLibraryName(libraryDTO.getLibraryName());
        library.setBaseInfo(new LibraryBaseInfoVO(libraryDTO.getIntroductory(), libraryDTO.getOpenTime()));
        library.setAddress(RepositoryFactory.get(IAddressRepository.class).get(libraryDTO.getCountryCode(), libraryDTO.getProvinceCode(), libraryDTO.getCityCode(), libraryDTO.getAddressDetail()));
        library.setAdmin(RepositoryFactory.get(IUserRepository.class).get(libraryDTO.getAdminUserId()));
        // 保存
        library.save();
    }

    private LibraryInfoDTO libraryToLibraryInfoDTO(LibraryEntity library) {
        LibraryInfoDTO dto = new LibraryInfoDTO();
        BeanUtil.copyProperties(library.getBaseInfo(), dto);
        dto.setLibraryId(library.getId());
        dto.setLibraryName(library.getLibraryName());
        dto.setAdminUserId(library.getAdmin().getUserId());
        dto.setAdminUserName(library.getAdmin().getUserName());
        AddressVO address = library.getAddress();
        dto.setAddress(address.getCountry().getCountryName() + address.getProvince().getProvinceName() + address.getCity().getCityName() + address.getDetail());
        return dto;
    }

    public LibraryInfoDTO getLibraryInfo(Long libraryId) {
        return libraryToLibraryInfoDTO(getLibraryEntity(libraryId));
    }

    public List<LibraryInfoDTO> listLibrary() {
        List<LibraryEntity> libraryList = RepositoryFactory.get(ILibraryRepository.class).allLibrary();
        if (CollectionUtil.isEmpty(libraryList)) {
            return Collections.emptyList();
        }
        List<LibraryInfoDTO> dtoList = new LinkedList<>();
        libraryList.forEach(library -> dtoList.add(libraryToLibraryInfoDTO(library)));
        return dtoList;
    }

    private LibraryEntity getLibraryEntity(Long libraryId) {
        LibraryEntity library = RepositoryFactory.get(ILibraryRepository.class).get(libraryId);
        if (null == library) {
            throw new DomainException("library not found!");
        }
        return library;
    }

    /**
     * 移除图书馆
     *
     * @param libraryId 图书馆ID
     */
    @Transactional
    public void removeLibrary(Long libraryId) {
        LibraryEntity library = getLibraryEntity(libraryId);
        library.remove();
    }

    /**
     * 修改图书馆基本信息
     *
     * @param dto 参数
     */
    @Transactional
    public void updateLibraryBaseMessage(LibraryBaseMessageDTO dto) {
        LibraryEntity library = getLibraryEntity(dto.getLibraryId());
        library.updateBaseInfoMessage(LibraryBaseInfoVO.builder().openTime(dto.getOpenTime()).introductory(dto.getIntroductory()).build());
    }

}
